#include "ActivityConfig.h"
#include "LogEx.h"
#include "Utils.h"
#include "Hall.h"
#include <string>
using namespace std;

SINGLETON_CLASS_INIT(CActivityConfigManager);

void CActivityConfigManager::Load(const char *file)
{
    pugi::xml_document doc;
	pugi::xml_parse_result result = doc.load_file( file );
    if( result.status != pugi::status_ok )
    {
        printf( "CActivityConfigManager::Load[%s] Error[%d]\n", file, (int)result );
        return;
    }

    pugi::xml_node cfg = doc.child( "Config" );
	if( cfg.empty() )
	{
        printf( "CActivityConfigManager::Load [%s] Error, not found child:Config\n", file );
		return;
	}
	
    u64 now = TIME_NOW;
    m_activity.clear();
    for( pugi::xml_node item = cfg.first_child(); item; item = item.next_sibling() )
	{
        ActivityItem e;

	    e.activityid = item.attribute("activityid").as_int();
	    e.gameid = item.attribute("gameid").as_int();

        if( e.gameid != 0 && e.gameid != CHall::Instance().GameId() )
        {
            // 此活动项不属于当前游戏
            continue;
        }

	    e.condition1 = item.attribute("condition1").as_int();
	    e.condition2 = item.attribute("condition2").as_int();
	    e.condition3 = item.attribute("condition3").as_int();
	    e.condition4 = item.attribute("condition4").as_int();
	    e.condition5 = (s64)item.attribute("condition5").as_double();
	    e.condition6 = (s64)item.attribute("condition6").as_double();
	    e.condition7 = (s64)item.attribute("condition7").as_double();
	    e.condition8 = (s64)item.attribute("condition8").as_double();
	    
        e.getawardtype = item.attribute("getawardtype").as_int();
        e.autoaward = item.attribute("autoaward").as_int();

        string tbegin = item.attribute("tbegin").as_string();
        string tend = item.attribute("tend").as_string();
        e.tbegin = Convert2Time( tbegin.c_str() );
        e.tend = Convert2Time( tend.c_str() );

        if( now > e.tbegin && now < e.tend )
        {
            _LoadAwards( e, item );
            m_activity[ e.activityid ] = e;

            LOG_INFO( "[%s][%s][%d] activityid[%d] gameid[%d] conn[%d,%d,%d,%d,%lld,%lld,%lld,%lld] time[%s-%s][%lld-%lld] getawardtype[%d]auto[%d]",
                    __FILE__, __FUNCTION__, __LINE__, 
                    e.activityid, e.gameid, e.condition1, e.condition2, e.condition3, e.condition4,
                    e.condition5, e.condition6, e.condition7, e.condition8,
                    tbegin.c_str(), tend.c_str(), e.tbegin, e.tend,
                    e.getawardtype, e.autoaward );
        }
    }
}

ActivityItem* CActivityConfigManager::FindActivity(s32 activityid)
{
    std::map<s32, ActivityItem>::iterator it = m_activity.find( activityid );
    if( it != m_activity.end() )
    {
        return &(it->second);
    }
    return NULL;
}

void CActivityConfigManager::GetAwards(s32 activityid, std::vector<publicproto::AwardInfo> &awards)
{
    ActivityItem *aitem = FindActivity( activityid );
    if( !aitem )
    {
        LOG_ERROR( "[%s][%s][%d] activityid[%d] not found",
            __FILE__, __FUNCTION__, __LINE__, activityid );
        return;
    }
    GetAwards( *aitem, awards );
}

void CActivityConfigManager::GetAwards(ActivityItem &activity, std::vector<publicproto::AwardInfo> &awards)
{
    awards.clear();
    if( activity.getawardtype == 1 )
    {
        // 获得所有配置的奖励
        std::vector<ActivityAward>::iterator it = activity.awards.begin();
        for( ; it != activity.awards.end(); ++it )
        {
            awards.push_back( it->award );
        }
    }
    else if( activity.getawardtype == 2 )
    {
        // 从多个奖励中抽取一个
        int p = rand() % 100;
        int curprob = 0;
        int idx = activity.defaultAwardIdx;
        u64 now = TIME_NOW;
        std::vector<ActivityAward>::iterator it = activity.awards.begin();
        for( int i=0; it != activity.awards.end(); ++it, ++i )
        {
            if( !IsSameDay(now, it->lastGetTime) )
            {
                it->curGet = 0;
            }

            curprob += it->prob;
            if( p < curprob && it->curGet < it->dailyLimit )
            {
                // 找到了
                idx = i;
                break;
            }
        }
        awards.push_back( activity.awards[idx].award );
        ++activity.awards[idx].curGet;
        activity.awards[idx].lastGetTime = now;
    }
    else
    {
        LOG_ERROR( "[%s][%s][%d] activityid[%d] gettype[%d]",
            __FILE__, __FUNCTION__, __LINE__, activity.activityid, activity.getawardtype );
        return;
    }
    LOG_DEBUG( "[%s][%s][%d] activityid[%d] awardcount[%d]",
        __FILE__, __FUNCTION__, __LINE__, activity.activityid, (s32)awards.size() );
}

void CActivityConfigManager::_LoadAwards(ActivityItem &item, pugi::xml_node &awards)
{
    for( pugi::xml_node node = awards.first_child(); node; node = node.next_sibling() )
	{
        ActivityAward a;
        a.id = node.attribute("id").as_int();
	    a.award.type = node.attribute("type").as_int();
	    a.award.val = node.attribute("val").as_int();
	    a.award.count = node.attribute("count").as_int();
	    a.award.reserve = node.attribute("reserve").as_int();
        
        a.dailyLimit = node.attribute("dailylimit").as_int();
        a.prob = node.attribute("prob").as_int();;
        a.curGet = 0;
        a.lastGetTime = TIME_NOW;
        item.awards.push_back( a );
        
        if( a.dailyLimit == 0 )
        {
            item.defaultAwardIdx = (s32)item.awards.size() - 1;
        }
        
        LOG_INFO( "[%s][%s][%d] activityid[%d] award[%d,%d,%d,%d] prob[%d] dailylimit[%d] defaultIdx[%d]",
            __FILE__, __FUNCTION__, __LINE__, 
            item.activityid, a.award.type, a.award.val, a.award.count, a.award.reserve,
            a.prob, a.dailyLimit, item.defaultAwardIdx );
    }
}

